Linter: Implement a11y-no-redundant-image-alt rule#1686
Conversation
Implement the `a11y-no-redundant-image-alt` linter rule, ported from erblint-github's `GitHub::Accessibility::NoRedundantImageAlt`. This rule flags `<img>` elements whose `alt` attribute contains the words "image" or "picture", since screen readers already announce the element as an image, making these words redundant. The rule performs a case-insensitive whole-word match and skips dynamic ERB attribute values. Descriptive medium words like "screenshot", "photograph", and "painting" are allowed, as they convey meaningful context about the image content. **New files:** - `a11y-no-redundant-image-alt.ts` — Rule implementation using the `HTMLElementNode` visitor pattern with `getAttributeValue` for static alt text inspection - `a11y-no-redundant-image-alt.test.ts` — 18 test cases covering valid alts, redundant words, case insensitivity, empty/missing alts, dynamic ERB values, substring false positives, and ERB helpers **Configuration:** Disabled by default, warning severity. Closes marcoroth#1224 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bffd0e5 to
b54ca5c
Compare
marcoroth
left a comment
There was a problem hiding this comment.
Hey @joelhawksley, thanks for working on this!
It looks like we are missing docs pages for these linter rules here: https://github.com/marcoroth/herb/tree/main/javascript/packages/linter/docs/rules
Would you mind adding a docs page matching the style of the others and adding an entry to the README in javascript/packages/linter/docs/rules/README.md.
Thank you! 🙏🏼
390aee8 to
b54ca5c
Compare
|
@marcoroth updated! I also added a test to make sure all rules have docs pages and a link in the README, fixing a couple other missing links. |
| describe("rule documentation completeness", () => { | ||
| const ruleNames = rules.map((r) => r.ruleName) | ||
|
|
||
| test.each(ruleNames)("%s has a docs page", (ruleName) => { |
There was a problem hiding this comment.
Great idea, thanks for this! 🙏🏼
|
|
||
| export class A11yNoRedundantImageAltRule extends ParserRule { | ||
| static ruleName = "a11y-no-redundant-image-alt" | ||
| static introducedIn = this.version("0.9.7") |
There was a problem hiding this comment.
Lets keep the new rules as unreleased so we can bump them to the right version when cutting a release
| static introducedIn = this.version("0.9.7") | |
| static introducedIn = this.version("unreleased") |
Signed-off-by: Marco Roth <marco.roth@intergga.ch>
Implement the
a11y-no-redundant-image-altlinter rule, ported from erblint-github'sGitHub::Accessibility::NoRedundantImageAlt.This rule flags
<img>elements whosealtattribute contains the words "image" or "picture", since screen readers already announce the element as an image, making these words redundant. The rule performs a case-insensitive whole-word match and skips dynamic ERB attribute values.Descriptive medium words like "screenshot", "photograph", and "painting" are allowed, as they convey meaningful context about the image content.
Examples
❌ Incorrect:
✅ Correct:
Changes
New files:
a11y-no-redundant-image-alt.ts— Rule implementation using theHTMLElementNodevisitor pattern withgetAttributeValuefor static alt text inspectiona11y-no-redundant-image-alt.test.ts— 18 test cases covering valid alts, redundant words, case insensitivity, empty/missing alts, dynamic ERB values, substring false positives, and ERB helpersModified files:
rules.ts— Register rule in the rules arrayrules/index.ts— Add re-exportConfiguration: Disabled by default, warning severity.
References
Closes #1224